package com.chen.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.dto.ChooseSubDTO;
import com.chen.dto.ImportDTO;
import com.chen.dto.SubjectDTO;
import com.chen.dto.SubjectImportDTO;
import com.chen.entity.ExamPaper;
import com.chen.entity.ExamPaperConnectSubject;
import com.chen.entity.Subject;
import com.chen.mapper.ExamChooseMapper;
import com.chen.mapper.ExamPaperConnectSubjectMapper;
import com.chen.mapper.ExamPaperMapper;
import com.chen.mapper.SubjectMapper;
import com.chen.service.SubjectService;
import com.chen.utils.MyExcelUtil;
import com.chen.vo.SubjectVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 试题
 */
@Service
public class SubjectServiceImpl extends ServiceImpl<SubjectMapper, Subject> implements SubjectService {

    // 试卷
    @Autowired
    private ExamPaperMapper examPaperMapper;

    // 试卷试题连接表
    @Autowired
    private ExamPaperConnectSubjectMapper examPaperConnectSubjectMapper;

    // 答题记录
    @Autowired
    private ExamChooseMapper examChooseMapper;

    @Override
    public List<SubjectVO> pageList(Integer subjectId, Integer courseId, Integer gradeId, Integer index, Integer pageShow) {
        return baseMapper.pageList(subjectId, courseId, gradeId, index, pageShow);
    }

    @Override
    public SubjectVO getSubjectById(Integer subjectId) {
        return baseMapper.getSubjectById(subjectId);
    }

    /**
     * 试卷与试题绑定
     * @param chooseSubDTO
     * @return
     */
    @Override
    @Transactional
    public Integer saveExamPaper(ChooseSubDTO chooseSubDTO) {
        Integer examPaperId = chooseSubDTO.getExamPaperId();
        Integer subjectId = chooseSubDTO.getSubjectId();
        Integer score = chooseSubDTO.getScore();
        if (ObjectUtil.isNotEmpty(examPaperId) && ObjectUtil.isNotEmpty(subjectId) && ObjectUtil.isNotEmpty(score)) {
            Long countByExamPaperIdAndSubjectId = examPaperConnectSubjectMapper.findCountByExamPaperIdAndSubjectId(examPaperId, subjectId);
            if (countByExamPaperIdAndSubjectId == 0) {
                // 1. 判断该题是否存在
                ExamPaperConnectSubject examPaperConnectSubject = examPaperConnectSubjectMapper.findConnecByExamPaperIdAndSubjectId(examPaperId, subjectId);
                if (ObjectUtil.isEmpty(examPaperConnectSubject)) {
                    // 2. 添加试题关联
                    ExamPaperConnectSubject connectSubject = ExamPaperConnectSubject.builder().examPaperId(examPaperId).subjectId(subjectId).build();
                    examPaperConnectSubjectMapper.insert(connectSubject);
                    // 3. 修改试卷分数
                    examPaperMapper.addScoreById(examPaperId, score);
                    return 1;
                }
            }
        }
        return 0;
    }

    /**
     * 编辑试题信息
     * @param dto
     * @return
     */
    @Override
    public Integer updateSubject(SubjectDTO dto) {
        Integer id = dto.getId();
        if (ObjectUtil.isNotEmpty(id)) {
            Subject subject = BeanUtil.toBean(dto, Subject.class);
            return baseMapper.updateById(subject);
        }
        return 0;
    }

    /**
     * 新增试题信息
     * @param dto
     * @return
     */
    @Override
    public Integer addSubject(SubjectDTO dto) {
        Subject subject = BeanUtil.toBean(dto, Subject.class);
        return baseMapper.insert(subject);
    }

    /**
     * 删除试题信息
     * @param subjectId
     * @return
     */
    @Override
    public Integer delById(Integer subjectId) {
        if (ObjectUtil.isNotEmpty(subjectId)) {
            // 答题个数
            Long countBySubjectId = examChooseMapper.findCountBySubjectId(subjectId);
            // 试卷绑定个数
            Long countBySubjectId1 = examPaperConnectSubjectMapper.findCountBySubjectId(subjectId);
            // 没有绑定信息才能删除
            if (countBySubjectId == 0 && countBySubjectId1 == 0) {
                return baseMapper.deleteById(subjectId);
            }
        }
        return 0;
    }

    /**
     * 导入数据
     * @param importDTO
     * @return
     */
    @Override
    @Transactional
    public Integer importData(ImportDTO importDTO) {
        // 若文件为空则不做任何处理
        MultipartFile excel = importDTO.getInputfile();
        if (excel.getSize() <= 0) {
            return 0;
        }
        // 1.从Excel中获取数据
        List<SubjectImportDTO> excelDatas = new ArrayList<>();
        InputStream excelIs = null;
        try {
            excelIs = excel.getInputStream();
            excelDatas = MyExcelUtil.readToBean(excel.getInputStream(), SubjectImportDTO.class);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e){
            e.printStackTrace();
        } finally {
            // 关闭上传Excel文件输入流
            if (excelIs != null) {
                try {
                    excelIs.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        if (CollectionUtil.isEmpty(excelDatas))
            return 0;

        // 将excel中的试题数据转为数据库bean对应数据
        List<Subject> subjectList = new ArrayList<>();
        excelDatas.forEach(data -> {
            Integer type = 0;
            if ("单选".equals(data.getType())) {
                type = 0;
            }else if ("多选".equals(data.getType())) {
                type = 1;
            }else if ("简答题".equals(data.getType())) {
                type = 2;
            }
            Integer easy = 0;
            if ("简单".equals(data.getEasy())) {
                easy = 0;
            }else if ("普通".equals(data.getEasy())) {
                easy = 1;
            }else if ("困难".equals(data.getEasy())) {
                easy = 2;
            }
            Subject subject = Subject.builder()
                    .name(StrUtil.blankToDefault(data.getName(), ""))
                    .optionA(StrUtil.blankToDefault(data.getOptionA(), ""))
                    .optionB(StrUtil.blankToDefault(data.getOptionB(), ""))
                    .optionC(StrUtil.blankToDefault(data.getOptionC(), ""))
                    .optionD(StrUtil.blankToDefault(data.getOptionD(), ""))
                    .rightResult(StrUtil.blankToDefault(data.getRightResult(), ""))
                    .score(data.getScore())
                    .type(type)
                    .courseId(importDTO.getCourseId())
                    .gradeId(importDTO.getGradeId())
                    .easy(easy)
                    .division(importDTO.getDivision())
                    .build();
            subjectList.add(subject);
        });

        if (CollectionUtil.isEmpty(subjectList))
            return 0;

        // 导入类型
        String importOption = importDTO.getImportOption();
        // 只导入试题
        this.saveBatch(subjectList);
        if ("1".equals(importOption)) {
            // 导入到已有试卷
            // 试卷id
            Integer examPaperId = importDTO.getExamPaperId();
            AtomicReference<Integer> totalScocre = new AtomicReference<>(0);
            // 导入的试题关联试卷
            subjectList.forEach(sub -> {
                ExamPaperConnectSubject connectSubject = ExamPaperConnectSubject.builder().examPaperId(examPaperId).subjectId(sub.getId()).build();
                examPaperConnectSubjectMapper.insert(connectSubject);
                totalScocre.updateAndGet(v -> v + sub.getScore());
            });
            // 修改试卷总分
            examPaperMapper.addScoreById(examPaperId, totalScocre.get());
        }else if ("2".equals(importOption)) {
            // 添加到新建试卷
            // 试卷名
            String examPaperName = importDTO.getExamPaperName();
            Assert.isTrue(ObjectUtil.isNotEmpty(examPaperName), "试卷名不能为空");
            // 试卷难易程度
            Integer examPaperEasy = importDTO.getExamPaperEasy();
            Assert.isTrue(ObjectUtil.isNotEmpty(examPaperEasy), "试卷难易程度不能为空");
            // 考试时长
            Integer examPaperTime = importDTO.getExamPaperTime();
            Assert.isTrue(ObjectUtil.isNotEmpty(examPaperTime), "考试时长不能为空");
            // 分数
            int totalScore = subjectList.stream().mapToInt(Subject::getScore).sum();
            // 组装试卷
            ExamPaper examPaper = ExamPaper.builder().name(examPaperName).easy(examPaperEasy).duration(examPaperTime).score(totalScore).gradeId(importDTO.getGradeId()).division(importDTO.getDivision()).build();
            // 插入试卷信息
            examPaperMapper.insert(examPaper);
            // 关联试卷绑定
            subjectList.forEach(sub -> {
                ExamPaperConnectSubject connectSubject = ExamPaperConnectSubject.builder().examPaperId(examPaper.getId()).subjectId(sub.getId()).build();
                examPaperConnectSubjectMapper.insert(connectSubject);
            });
            return subjectList.size();
        }
        return 0;
    }
}
